import * as THREE from 'three' //导入整个 three.js核心库
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' //导入控制器模块，轨道控制器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' //导入GLTF模块，模型解析器,根据文件格式来定
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'
import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'
import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'
import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js'
import { CSS3DRenderer } from 'three/addons/renderers/CSS3DRenderer.js';
import { ElMessage } from 'element-plus';

// import * as dat from 'dat.gui';
import flvjs from 'flv.js';
import { onlyKey, getAssetsFile } from '@/utils/utilityFunction'
import modulesPrototype from './modelEditClass/index'
import TWEEN from "@tweenjs/tween.js";
import { vertexShader, fragmentShader } from '@/config/constant.js'
class renderModel {
  constructor(selector) {
    this.container = document.querySelector(selector)
    // 相机
    this.camera
    // 场景
    this.scene = null
    //渲染器
    this.renderer
    // 控制器
    this.controls
    // 模型
    this.model
    // 几何体模型数组
    this.geometryGroup = new THREE.Group()
    // 多模型数组
    this.manyModelGroup = new THREE.Group()
    // 加载进度监听
    this.loadingManager = new THREE.LoadingManager()
    //文件加载器类型
    this.fileLoaderMap = {
      'glb': new GLTFLoader(),
      'fbx': new FBXLoader(this.loadingManager),
      'gltf': new GLTFLoader(),
      'obj': new OBJLoader(this.loadingManager),
      'stl': new STLLoader(),
    }
    //模型动画列表
    this.modelAnimation
    //模型动画对象
    this.animationMixer
    this.animationClock = new THREE.Clock()
    //动画帧
    this.animationFrame = null
    // 轴动画帧
    this.rotationAnimationFrame = null
    // 动画构造器
    this.animateClipAction = null
    // 动画循环方式枚举
    this.loopMap = {
      LoopOnce: THREE.LoopOnce,
      LoopRepeat: THREE.LoopRepeat,
      LoopPingPong: THREE.LoopPingPong
    }
    // 网格辅助线
    this.gridHelper
    // 坐标轴辅助线
    this.axesHelper
    // 环境光
    this.ambientLight
    //平行光
    this.directionalLight
    // 平行光辅助线
    this.directionalLightHelper
    // 点光源
    this.pointLight
    //点光源辅助线
    this.pointLightHelper
    //聚光灯
    this.spotLight
    //聚光灯辅助线
    this.spotLightHelper
    //模型平面
    this.planeGeometry
    //模型材质列表
    this.modelMaterialList = []
    // 模型材质原始数据缓存
    this.originalMaterials = new Map()
    // 效果合成器
    this.effectComposer
    this.outlinePass
    // 动画渲染器
    this.renderAnimation = null
    // 碰撞检测
    this.raycaster = new THREE.Raycaster()
    // 鼠标位置
    this.mouse = new THREE.Vector2()
    // 辉光效果合成器
    this.glowComposer
    this.glowRenderPass
    // 辉光渲染器
    this.unrealBloomPass
    // 辉光着色器
    this.shaderPass
    // 需要辉光的材质
    this.glowMaterialList
    this.materials = {}
    // 拖拽对象控制器
    this.transformControls
    // 是否开启辉光
    this.glowUnrealBloomPass = false
    // 窗口变化监听事件
    this.onWindowResizesListener
    // 鼠标点击事件
    this.onMouseClickListener
    // 鼠标悬浮事件
    this.onMouseHoverListener
    this.onScale
    // 模型上传进度条回调函数
    this.modelProgressCallback = (e) => e
    // 当前拖拽的几何模型
    this.dragGeometryModel = {}
    // 当前模型加载状态
    this.loadingStatus = true
    // 3d文字渲染器
    this.css3DRenderer = null
    // 3d文字控制器
    this.css3dControls = null
    // 当前拖拽标签信息
    this.dragTag = {}
    //当前标签列表
    this.dragTagList = []
    // 当前拖拽模型信息
    this.activeDragManyModel = {}
    // 当前相机位置
    this.cameraPosition = {}
    // 当前场景全部模型列表
    this.modelList = []
    //  当前gui
    this.gui = null
    // 上一次禁用位置
    this.oldDisablePosition = ''
    // 上一次中间模型位置渲染结果
    this.oldCenterDnShow = false;
    // right电脑名称
    this.rightDn = ['diannao006', 'diannao007', 'diannao008']
    // left电脑名称
    this.leftDn = ['diannao001', 'diannao002', 'diannao003']
    // center电脑名称
    this.centerDn = ['diannao004']
    // rightbtn电脑名称
    this.rightBtnDn = ['diannao005']
    this.rightBtnDnShow = false;
    // leftbtn电脑名称
    this.leftBtnDn = ['diannao009']
    this.leftBtnDnShow = false;
    // 旋转角度
    this.rotateAngle = { x: 0, y: 0, z: 0 }
    // token
    this.token = '/flv/live/stream_21_0.flv?play_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzAxOTQyOTIsImlzcyI6InRzaW5nc2VlLWVhc3ljdnIifQ.mvg9jGty0fQGu0-gBuqGcd677UMBGdi5qGfZDdGW_iM'
    this.token2 = '/flv/live/stream_211_0.flv?play_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzAxOTQ5NDgsImlzcyI6InRzaW5nc2VlLWVhc3ljdnIifQ.V1FQfocAdXaFzwI0v-MhD6FXsOMnFUBY6rV7u8eK_Hc'
    this.token3 = '/flv/live/stream_224_0.flv?play_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzAxOTQzNzAsImlzcyI6InRzaW5nc2VlLWVhc3ljdnIifQ.f7eX0obocPneYDmTZk2vwwgGwzuRMkMFNXyTEzKG9GQ'
    // 延时函数
    this.dragTimer;
    // 保存当前点击对象
    this.currentModelItem
  }
  init() {
    return new Promise(async (resolve, reject) => {
      //初始化场景
      this.initScene()
      //初始化渲染器
      this.initRender()
      //初始化相机
      this.initCamera()
      //初始化控制器，控制摄像头,控制器一定要在渲染器后
      this.initControls()
      // 创建辅助线
      this.createHelper()
      // 创建灯光
      this.createLight()
      // 加载flv视频流
      this.loadFLVVideo()
      // 初始化gui
      // this.initGUI()
      this.addEvenListMouseListener()
      // 添加物体模型 TODO：初始化时需要默认一个
      //  https://threejs.org/examples/models/gltf/LittlestTokyo.glb
      const load = await this.setModel({
        filePath: 'model/22/main.gltf',
        fileType: 'gltf',
        decomposeName: 'transformers_3'
      })
      // 创建效果合成器
      this.createEffectComposer()
      //场景渲染
      this.sceneAnimation()
      resolve(load)
    })
  }
  // 创建场景
  async initScene() {
    this.scene = new THREE.Scene()
    const texture = new THREE.TextureLoader().load(getAssetsFile('image/model-bg-2.jpeg'))
    this.scene.background = texture
    this.scene.backgroundIntensity = 1
    texture.dispose()
  }
  // 创建相机
  initCamera() {
    const { clientHeight, clientWidth } = this.container
    this.camera = new THREE.PerspectiveCamera(50, clientWidth / clientHeight, 0.01, 10000)
    this.camera.fov = 50;
    this.camera.lookAt(1000, 200, 0)
    this.camera.updateProjectionMatrix();
  }
  // 创建渲染器
  initRender() {
    this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, preserveDrawingBuffer: true }) //设置抗锯齿
    //设置屏幕像素比
    this.renderer.setPixelRatio(window.devicePixelRatio)
    //渲染的尺寸大小
    const { clientHeight, clientWidth } = this.container
    this.renderer.setSize(clientWidth, clientHeight)
    //色调映射
    this.renderer.toneMapping = THREE.ReinhardToneMapping
    this.renderer.autoClear = true
    this.renderer.outputColorSpace = THREE.SRGBColorSpace
    //曝光
    // this.renderer.toneMappingExposure = 2
    // this.renderer.shadowMap.enabled = true
    // this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
    // const axesHelper = new THREE.AxesHelper(5);
    // this.scene.add(axesHelper);
    this.container.appendChild(this.renderer.domElement)
    // 创建一个CSS3DRenderer
    this.css3DRenderer = new CSS3DRenderer();
    this.css3DRenderer.setSize(clientWidth, clientHeight);
    this.css3DRenderer.domElement.style.position = 'absolute';
    this.css3DRenderer.domElement.style.pointerEvents = 'none';
    this.css3DRenderer.domElement.style.top = 0;
  }
  // 更新场景
  sceneAnimation() {
    this.renderAnimation = requestAnimationFrame(() => this.sceneAnimation())
    // 更新当前相机坐标位置
    this.getCameraPosition();
    // 等模型加载和相关数据处理完成在执行
    if (this.loadingStatus) {
      //辉光效果开关开启时执行
      if (this.glowUnrealBloomPass) {
        // 将不需要处理辉光的材质进行存储备份
        this.setMeshFlow()
      } else {
        this.effectComposer.render()
        this.controls.update()
      }
      TWEEN.update();
      // 3d标签渲染器
      if (this.dragTagList.length) {
        this.css3DRenderer.render(this.scene, this.camera)
        this.css3dControls.update()
      }
    }
  }
  // 监听事件
  addEvenListMouseListener() {
    //监听场景大小改变，跳转渲染尺寸
    this.onWindowResizesListener = this.onWindowResizes.bind(this)
    window.addEventListener("resize", this.onWindowResizesListener)
    // 鼠标点击
    this.onMouseClickListener = this.onMouseClickModel.bind(this)
    this.container.addEventListener('click', this.onMouseClickListener)


    // 鼠标悬浮
    this.onMouseHoverListener = this.onMouseHoverModel.bind(this)
    this.container.addEventListener('mouseover', this.onMouseHoverListener)
    // // 监听鼠标滚轮事件
    // this.onScale = this.scale.bind(this)
    // document.addEventListener('wheel', this.onScale)
  }
  scale(event) {
    const cameraPosition = this.camera.getWorldPosition(new THREE.Vector3());
    console.log(cameraPosition);
    if (event.deltaY >= -0) {
      this.controls.enableZoom = cameraPosition.z <= 1.8606189215608273;
      this.controls.maxAzimuthAngle = 0.18 //水平旋转的角度上限
      this.controls.minAzimuthAngle = -0.4 //水平旋转的角度下限
      this.controls.update()
    }
    // 如果向下滚动
    else {
      this.controls.enableZoom = true
      // if (cameraPosition.z < 5.94) {
      //   this.controls.maxAzimuthAngle = Infinity //水平旋转的角度上限
      //   this.controls.minAzimuthAngle = -Infinity
      //   this.controls.update()
      // } else {
      //   this.controls.maxAzimuthAngle = 0.18 //水平旋转的角度上限
      //   this.controls.minAzimuthAngle = -0.4 //水平旋转的角度下限
      //   this.controls.update()
      // }
    }
  }
  // 创建控制器
  initControls() {
    this.controls = new OrbitControls(this.camera, this.renderer.domElement)
    // this.controls.minDistance = 0.1;
    // this.controls.maxDistance = -0.1;
    // this.controls.enablePan = false//禁止平移
    // this.controls.maxPolarAngle = 1.5 //垂直旋转的角度的上限
    // this.controls.minPolarAngle = 1.35 //垂直旋转的角度的下限
    // this.controls.maxAzimuthAngle = 0.18 //水平旋转的角度上限
    // this.controls.minAzimuthAngle = -0.4 //水平旋转的角度下限
    // this.controls.target = new THREE.Vector3(0.12, 1.9, 5.8)
    // this.controls.enableRotate = false//禁止旋转
    // this.controls.enableZoom = false//禁止缩放
    // this.controls.enableDamping = true;
    // this.controls.target.set(0.0, 1.9, 5.8);
    this.controls.target.set(0.5, 0.15, 0);
    this.controls.update()
    //标签控制器
    this.css3dControls = new OrbitControls(this.camera, this.css3DRenderer.domElement)
    // this.css3dControls.minDistance = 0.00000000000001;
    // this.css3dControls.maxDistance = 0.0000000000001;
    // this.css3dControls.enablePan = false//禁止平移
    // this.css3dControls.maxPolarAngle = 0.18
    // this.css3dControls.minPolarAngle = -0.6
    // this.css3dControls.maxAzimuthAngle = 0.18
    // this.css3dControls.minAzimuthAngle = -0.6
    // this.css3dControls.target = new THREE.Vector3(0.5, 1.7, 4.8)
    // this.css3dControls.enableRotate = false//禁止旋转
    // this.css3dControls.enableZoom = false//禁止缩放
    // this.css3dControls.enableDamping = true;
    this.css3dControls.target.set(0.6, 1.7, 4.8);
    this.css3dControls.update()
  }
  // 
  // 获取当前镜头位置
 async getCameraPosition() {
    this.cameraPosition = this.camera.position;
    // console.log(this.cameraPosition, '当前镜头位置');
    let currentPosition = [];
    // 当前禁用位置
    let disablePosition = '';
    // 当次中心位置渲染的模型结果
    let centerDnShow = false;
    // 需要显示的模型名称
    let showModelName = [];
    // 判断坐标选中禁用区域
    if (this.cameraPosition.x > 0.369 && this.cameraPosition.x < 0.95) {
      disablePosition = 'left';
    } else if (this.cameraPosition.x < 0.098 && this.cameraPosition.x > -0.4) {
      disablePosition = 'right';
    }else{
      disablePosition = '';
    }
    if (this.cameraPosition.z > 0.89 && this.cameraPosition.z < 1.97) {
      centerDnShow = true;
    }
    let that = this;
    // 判断是否渲染正中心的电脑画面
    if (centerDnShow == true) {
      showModelName = [...showModelName, ...this.centerDn];
    }
    // 将会议室内分成两部分（以坐标区分）分别保存 各区域的的电脑模型名称
    switch (disablePosition) {
      case 'right':
        //如果是隐藏右边那么就渲染左侧的电脑模型画面
        showModelName = [...showModelName, ...that.leftDn];
        // 需要添加左后侧的电脑模型画面
        showModelName = [...showModelName, ...that.leftBtnDn]
        // showModelName = this.modelList.filter(item => item.newWorldPosition && item.newWorldPosition.x < 0.1).map(item => item.name);
        break;
      case 'left':
        //如果是隐藏左边那么就渲染右侧的电脑模型画面
        showModelName = [...showModelName, ...that.rightDn];
        // 需要添加右后侧的电脑模型画面
        showModelName = [...showModelName, ...that.rightBtnDn]
        // showModelName = this.modelList.filter(item => item.newWorldPosition && item.newWorldPosition.x > 0.1).map(item => item.name);
        break;
    }
    // console.log(showModelName, '需要渲染的模型名称');
    // 如果相机还是在上次渲染的区域那么就不需要重心计算渲染
    if (this.oldDisablePosition == disablePosition && this.oldCenterDnShow == centerDnShow) {
      return;
    }
    this.modelList.filter((item,index) => {
      if (showModelName.includes(item.name) && item.newWorldPosition) {
         function getModelCorners(mesh) {
          const box = new THREE.Box3().setFromObject(mesh); // 获取模型的边界框
          // console.log('当前模型四个顶点的坐标', mesh);
          currentPosition = [
            new THREE.Vector3(box.min.x, box.min.y, box.min.z),
            new THREE.Vector3(box.max.x, box.min.y, box.min.z),
            new THREE.Vector3(box.max.x, box.max.y, box.min.z),
            new THREE.Vector3(box.min.x, box.max.y, box.min.z)
          ];
          // 如果需要将局部坐标转换为世界坐标
          currentPosition.forEach(corner => {
            mesh.localToWorld(corner); // 将局部坐标转换为世界坐标
          });
          return currentPosition;
        }
        // 假设你已经获取到了四个顶点的坐标
        const corners = getModelCorners(item);
        // console.log(corners, '当前模型四个顶点的坐标');
        // 计算中心点
        const center = new THREE.Vector3();
        corners.forEach(corner => center.add(corner));
        center.divideScalar(corners.length);
        let videoTexture = null;
        let videoElement = null;
        let flvPlayer = null;
        // // 创建一个视频元素
        videoElement = document.createElement('video');
        videoElement.autoplay = true;
        videoElement.muted = true;
        videoElement.loop = true;
        videoElement.style.display = 'none'; // 隐藏视频元素
        // 检查浏览器是否支持 flv.js
        if (flvjs.isSupported()) {
          flvPlayer =  flvjs.createPlayer({
            type: 'flv',
            url: '/flv' + index%2==0?that.token3:that.token2, // 替换成你的视频流 URL
          });
          console.log(index%2==0?that.token:that.token2, 'flvPlayer');
          console.log(flvPlayer, 'flvPlayer');
          flvPlayer.attachMediaElement(videoElement);
          flvPlayer.load();
          flvPlayer.play();
          // 创建一个 Three.js 视频纹理
          videoTexture =  new THREE.VideoTexture(videoElement);
        }

        // 创建矩形的平面几何体
        // const geometry = new THREE.PlaneGeometry(1, 1); // 初始的单位矩形
        const geometry = new THREE.BoxGeometry(1, 1, 1);
        // const geometryGlass= new THREE.BoxGeometry(1, 1, 1);
        // 计算矩形的大小
        const width = corners[1].distanceTo(corners[0]);
        const height = corners[3].distanceTo(corners[0]);
        // 缩放矩形到合适的大小
        geometry.scale(0.1075, 0.059815, 0.0001);
        // geometryGlass.scale(0.1059, 0.059115, 0.0001);
        // 创建矩形的材质和网格---创建立体视频容器
        const material = new THREE.MeshBasicMaterial({ map: this.videoTexture, side: THREE.DoubleSide });
        // 创建矩形的材质
        // const material = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide });
        // const material = new THREE.MeshPhysicalMaterial({
        //   color: 0xffffff,
        //   metalness: 0,
        //   roughness: 0,
        //   transmission: 1,
        //   transparent: true,
        //   // map: this.videoTexture
        // })
        const plane = new THREE.Mesh(geometry, material);
        // const planeGlass = new THREE.Mesh(geometryGlass, materialGlass);
        // 设置矩形的位置和旋转
        plane.position.copy(center);
        // planeGlass.position.copy(center);
        // 计算矩形的旋转方向
        const edge1 = new THREE.Vector3().subVectors(corners[1], corners[0]).normalize(); // 边的方向
        const edge2 = new THREE.Vector3().subVectors(corners[3], corners[0]).normalize(); // 另一条边的方向
        // 使用法线确定矩形的朝向
        const normal = new THREE.Vector3().crossVectors(edge1, edge2).normalize();
        plane.lookAt(plane.position.clone().add(normal));
        // planeGlass.lookAt(plane.position.clone().add(normal));
        //
        if (!item.name.includes(that.centerDn)) {
          // 判断当前渲染侧进行偏移纠正
          switch (disablePosition) {
            case 'right':
              plane.position.x -= 0.0010905;
              // planeGlass.position.x -= 0.00105;
              break;
            case 'left':
              plane.position.x += 0.00109;
            // planeGlass.position.x += 0.00105;
          }
          plane.name = item.name + 'video_' + disablePosition;
          // planeGlass.name = item.name + 'videoGlass_' + disablePosition;
        } else {
          plane.position.z += 0.00109;
          // planeGlass.position.z -= 0.00105;
          plane.name = item.name + 'video_' + 'center';
          // planeGlass.name = item.name + 'videoGlass_' + 'center';
        }
        this.modelList.push(plane);
        // this.modelList.push(planeGlass);
        this.scene.add(plane);
        // this.scene.add(planeGlass);
      } else if (item.name.includes('video')) {
        // 执行删除
        if (that.centerDnShow != true || !item.name.includes(that.centerDn)) {
          console.log(item, '需要删除的模型');
          this.scene.remove(item);
        }
      }
      // 判断
    })
    // 执行完成后，将当前禁用位置保存到 oldDisablePosition
    this.oldDisablePosition = disablePosition;
    // 保存当前中心位置电脑的渲染结果 作为下一次渲染的参考以减少性能损耗
    this.oldCenterDnShow = centerDnShow
  }
  
  // 加载模型
  async setModel({ filePath, fileType, decomposeName }) {
    return new Promise((resolve, reject) => {
      this.loadingStatus = false
      // const THREE_PATH = `https://unpkg.com/three@0.${THREE.REVISION}.x`;
      let loader
      let that = this;
      if (['glb', 'gltf'].includes(fileType)) {
        const dracoLoader = new DRACOLoader()
        dracoLoader.setDecoderPath(`draco/gltf/`)
        dracoLoader.setDecoderConfig({ type: 'js' })
        dracoLoader.preload()
        new RGBELoader().load("model/royal_esplanade_1k.hdr", (texture) => {
          texture.mapping = THREE.EquirectangularReflectionMapping;
          that.scene.background = texture;
          that.scene.environment = texture;
          loader = new GLTFLoader().setDRACOLoader(dracoLoader)
          // todo
          loader.load(filePath, (result) => {
            switch (fileType) {
              case 'glb':
                this.model = result.scene
                break;
              case 'fbx':
                this.model = result
                break;
              case 'gltf':
                this.model = result.scene
                break;
              case 'obj':
                this.model = result
                break;
              case 'stl':
                const material = new THREE.MeshStandardMaterial();
                const mesh = new THREE.Mesh(result, material);
                this.model = mesh
                break;
              default:
                break;
            }
            this.model.decomposeName = decomposeName
            this.getModelMaterialList()
            this.setModelPositionSize()
            // 需要辉光的材质
            this.glowMaterialList = this.modelMaterialList.map(v => v.name)
            console.log(this.model, '模型')
            this.scene.add(this.model)
            this.loadingStatus = true
            this.model.rotation.y = - Math.PI / 2  //初始化模型的角度
            // this.model.rotation.x = -0.1  //初始化模型的角度
            // this.model.position.set(0, 0, 0)  //初始化模型的位置
            // this.controls.target = new THREE.Vector3(0.12, 1.9, 5.8)
            // 获取模型的包围盒
            // const box = new THREE.Box3().setFromObject(this.model);
            // 计算模型的中心位置
            // const center = new THREE.Vector3();
            // box.getCenter(center);
            // 将模型的位置设置为原点
            // this.model.position.sub(center);
            // 获取模型的包围盒
            const box = new THREE.Box3().setFromObject(this.model);
            // 计算模型的中心位置
            const center = new THREE.Vector3();
            box.getCenter(center);
            // 将模型的位置设置为原点
            this.model.position.copy(center).multiplyScalar(-1);
            // 设置相机轨道视角
            // {x: 0.18662671784444995, y: 0.44718280709310554, z: 1.7806189215608272}
            this.camera.position.set(-0.08662671784444995, 0.48718280709310554, 1.8606189215608272)
            let that = this;
            this.model.traverse(function (child) {
              if (child.isMesh && child.name.includes("diannao")) {
                // 如果子对象是 Mesh，获取它的世界坐标
                const worldPosition = new THREE.Vector3();
                child.getWorldPosition(worldPosition);
                // console.log(`${child.name} 的世界坐标:`, worldPosition);
                child.newWorldPosition = worldPosition;
                that.modelList.push(child);
              }
              if (child.isMesh && child.name.includes("ZhuanJia")) {
                // this.setExpertHover(child);
              }
            });

            resolve(true)
            this.getModelAnimaionList(result)
          }, (xhr) => {
            this.modelProgressCallback(xhr.loaded)
          }, (err) => {
            ElMessage.error('文件错误')
            console.log(err)
            resolve(true)
          })
        })
      } else {
        loader = this.fileLoaderMap[fileType]
      }
    })
  }
  // =============== 视频流FLV =================
  loadFLVVideo() {
    // 创建一个视频元素
    this.videoElement = document.createElement('video');
    this.videoElement.autoplay = true;
    this.videoElement.muted = true;
    this.videoElement.loop = true;
    this.videoElement.style.display = 'none'; // 隐藏视频元素
    // 检查浏览器是否支持 flv.js
    if (flvjs.isSupported()) {
      try {
        this.flvPlayer = flvjs.createPlayer({
          type: 'flv',
          url: '/flv' + this.token2, // 替换成你的视频流 URL
        });
        this.flvPlayer.attachMediaElement(this.videoElement);
        this.flvPlayer.load();
        this.flvPlayer.play();
        // 创建一个 Three.js 视频纹理
        this.videoTexture = new THREE.VideoTexture(this.videoElement);
        this.videoTexture.minFilter = THREE.LinearFilter;
        this.videoTexture.magFilter = THREE.LinearFilter;
        this.videoTexture.format = THREE.RGBFormat;
        // 创建一个材质并将视频纹理应用到材质上
        // const material = new THREE.MeshBasicMaterial({ map: this.videoTexture });
        const material = new THREE.MeshBasicMaterial({ map: this.videoTexture, side: THREE.DoubleSide });
        // 创建一个平面几何体并应用材质

        // const geometry = new THREE.PlaneGeometry(8, 4.5); // 16:9 的视频比例
        const geometry = new THREE.BoxGeometry(1, 1, 1);
        // 缩放矩形到合适的大小
        geometry.scale(1.1075, 1.059815,0.0001);
        // const geometry = new THREE.CircleGeometry(20, 64); // 16:9 的视频比例
        const mesh = new THREE.Mesh(geometry, material);
        mesh.scale.set(0.620, 0.355, 1.05); // 根据需要调整模型的大小
        mesh.position.set(0.23, 0.408, -0.11); // 根据需要调整模型的大小
        // 将平面添加到场景中
        this.scene.add(mesh);
      } catch (error) {
        console.log("加载视频流出错：", error);
      }

    }
  }
  // 设置材质辉光
  setMeshFlow() {
    this.scene.traverse((v) => {
      if (v instanceof THREE.GridHelper) {
        this.materials.gridHelper = v.material
        v.material = new THREE.MeshStandardMaterial({ color: '#000' })
      }
      if (v instanceof THREE.Scene) {
        this.materials.scene = v.background
        this.materials.environment = v.environment
        v.background = null
        v.environment = null
      }
      if (!this.glowMaterialList.includes(v.name) && v.isMesh) {
        this.materials[v.uuid] = v.material
        v.material = new THREE.MeshStandardMaterial({ color: '#000' })
      }
    })
    this.glowComposer.render()
    // 辉光渲染器执行完之后在恢复材质原效果
    this.scene.traverse((v) => {
      if (this.materials[v.uuid]) {
        v.material = this.materials[v.uuid]
        delete this.materials[v.uuid]
      }
      if (v instanceof THREE.GridHelper) {
        v.material = this.materials.gridHelper
        delete this.materials.gridHelper
      }
      if (v instanceof THREE.Scene) {
        v.background = this.materials.scene
        v.environment = this.materials.environment
        delete this.materials.scene
        delete this.materials.environment
      }
    })
    this.effectComposer.render()
    this.controls.update()
  }
  // 模型加载进度条回调函数
  onProgress(callback) {
    if (typeof callback == 'function') {
      this.modelProgressCallback = callback
    }
  }
  // 创建辅助线
  createHelper() {
    //网格辅助线
    // this.gridHelper = new THREE.GridHelper(6, 18, '#fff', 'rgb(193,193,193)');
    // this.gridHelper.position.set(0, -.59, -.1)
    // this.gridHelper.visible = false
    // this.scene.add(this.gridHelper)
    // 坐标轴辅助线
    // this.axesHelper = new THREE.AxesHelper(2);
    // this.axesHelper.visible = false
    // this.scene.add(this.axesHelper);
    // 开启阴影
    this.renderer.shadowMap.enabled = true;
  }
  // 创建光源
  createLight() {
    // 创建环境光
    this.ambientLight = new THREE.AmbientLight('#fff', .8)
    this.ambientLight.visible = true
    this.scene.add(this.ambientLight)
    // 创建平行光
    this.directionalLight = new THREE.DirectionalLight('#fff', 5)
    this.directionalLight1 = new THREE.DirectionalLight('#fff', 5)
    // this.directionalLight.position.set(-1.44, 2.2, 1)
    this.directionalLight.position.set(10, 10, 10)
    this.directionalLight1.position.set(-10, -10, -10)
    this.directionalLight.castShadow = true
    // this.directionalLight.visible = false
    // this.scene.add(this.directionalLight)
    // this.scene.add(this.directionalLight1)
    // 创建平行光辅助线
    this.directionalLightHelper = new THREE.DirectionalLightHelper(this.directionalLight, .3)
    this.directionalLightHelper.visible = false
    this.scene.add(this.directionalLightHelper)
    // 创建点光源
    this.pointLight = new THREE.PointLight(0xff0000, 5, 100)
    this.pointLight.visible = false
    this.scene.add(this.pointLight)
    // 创建点光源辅助线
    this.pointLightHelper = new THREE.PointLightHelper(this.pointLight, .5)
    this.pointLightHelper.visible = false
    this.scene.add(this.pointLightHelper)
    //  创建聚光灯
    this.spotLight = new THREE.SpotLight('#00BABD', 900);
    this.spotLight.visible = false
    this.spotLight.map = new THREE.TextureLoader().load(getAssetsFile('image/model-bg-1.jpg'));
    this.spotLight.map = new THREE.TextureLoader().load(getAssetsFile('image/model-bg-1.jpg'));
    this.spotLight.decay = 2;
    this.spotLight.shadow.mapSize.width = 1920;
    this.spotLight.shadow.mapSize.height = 1080;
    this.spotLight.shadow.camera.near = 1;
    this.spotLight.shadow.camera.far = 10;
    this.scene.add(this.spotLight);
    //创建聚光灯辅助线
    this.spotLightHelper = new THREE.SpotLightHelper(this.spotLight);
    this.spotLightHelper.visible = false
    this.scene.add(this.spotLightHelper)
    // 模型平面
    const geometry = new THREE.PlaneGeometry(4, 4);
    var groundMaterial = new THREE.MeshStandardMaterial({ color: '#000000' });
    this.planeGeometry = new THREE.Mesh(geometry, groundMaterial);
    this.planeGeometry.rotation.x = -Math.PI / 2
    this.planeGeometry.position.set(0, -1.2, 0)
    // 让地面接收阴影
    this.planeGeometry.receiveShadow = true;
    this.planeGeometry.visible = false
    this.scene.add(this.planeGeometry);
  }
  // 创建效果合成器
  createEffectComposer() {
    if (!this.container) return false
    const { clientHeight, clientWidth } = this.container
    this.effectComposer = new EffectComposer(this.renderer, new THREE.WebGLRenderTarget(clientWidth, clientHeight))
    // this.effectComposer = new EffectComposer(this.renderer)
    const renderPass = new RenderPass(this.scene, this.camera)
    this.effectComposer.addPass(renderPass)
    this.outlinePass = new OutlinePass(new THREE.Vector2(clientWidth, clientHeight), this.model, this.camera)
    this.outlinePass.visibleEdgeColor = new THREE.Color('#FF8C00') // 可见边缘的颜色
    this.outlinePass.hiddenEdgeColor = new THREE.Color('#8a90f3') // 不可见边缘的颜色
    this.outlinePass.edgeGlow = 2 // 发光强度
    this.outlinePass.usePatternTexture = false // 是否使用纹理图案
    this.outlinePass.edgeThickness = 1 // 边缘浓度
    this.outlinePass.edgeStrength = 4 // 边缘的强度，值越高边框范围越大
    this.outlinePass.pulsePeriod = 200 // 闪烁频率，值越大频率越低
    this.effectComposer.addPass(this.outlinePass)
    let outputPass = new OutputPass()
    this.effectComposer.addPass(outputPass)
    let effectFXAA = new ShaderPass(FXAAShader)
    const pixelRatio = this.renderer.getPixelRatio()
    effectFXAA.uniforms.resolution.value.set(1 / (clientWidth * pixelRatio), 1 / (clientHeight * pixelRatio))
    effectFXAA.renderToScreen = true
    effectFXAA.needsSwap = true
    this.effectComposer.addPass(effectFXAA)
    //创建辉光效果
    this.unrealBloomPass = new UnrealBloomPass(new THREE.Vector2(clientWidth, clientHeight), 1.5, 0.4, 0.85)
    // 辉光合成器
    const renderTargetParameters = {
      minFilter: THREE.LinearFilter,
      format: THREE.RGBAFormat,
      stencilBuffer: false,
    };
    const glowRender = new THREE.WebGLRenderTarget(clientWidth * 2, clientHeight * 2, renderTargetParameters)
    this.glowComposer = new EffectComposer(this.renderer, glowRender)
    this.glowComposer.renderToScreen = false
    this.glowRenderPass = new RenderPass(this.scene, this.camera)
    this.glowComposer.addPass(this.glowRenderPass)
    this.glowComposer.addPass(this.unrealBloomPass)
    // 着色器
    this.shaderPass = new ShaderPass(new THREE.ShaderMaterial({
      uniforms: {
        baseTexture: { value: null },
        bloomTexture: { value: this.glowComposer.renderTarget2.texture },
        tDiffuse: { value: null },
        glowColor: { value: null }
      },
      vertexShader,
      fragmentShader,
      defines: {}
    }), 'baseTexture')
    this.shaderPass.material.uniforms.glowColor.value = new THREE.Color();
    this.shaderPass.renderToScreen = true
    this.shaderPass.needsSwap = true
    this.shaderPass.name = 'ShaderColor'
  }
  // 监听窗口变化
  onWindowResizes() {
    if (!this.container) return false
    const { clientHeight, clientWidth } = this.container
    //调整屏幕大小
    this.camera.aspect = clientWidth / clientHeight // 摄像机宽高比例
    this.camera.updateProjectionMatrix() //相机更新矩阵，将3d内容投射到2d面上转换
    this.renderer.setSize(clientWidth, clientHeight)
    this.css3DRenderer.setSize(clientWidth, clientHeight)
    if (this.effectComposer) {
      // 假设抗锯齿效果是EffectComposer中的第一个pass
      var pass = this.effectComposer.passes[3]
      const pixelRatio = this.renderer.getPixelRatio()
      pass.uniforms.resolution.value.set(1 / (clientWidth * pixelRatio), 1 / (clientHeight * pixelRatio));
      this.effectComposer.setSize(clientWidth, clientHeight)
    }
    if (this.glowComposer) this.glowComposer.setSize(clientWidth, clientHeight)
  }
  // 清除模型数据
  onClearModelData() {
    cancelAnimationFrame(this.rotationAnimationFrame)
    cancelAnimationFrame(this.renderAnimation)
    cancelAnimationFrame(this.animationFrame)
    this.container.removeEventListener('click', this.onMouseClickListener)
    window.removeEventListener("resize", this.onWindowResizesListener)
    this.scene.traverse((v) => {
      if (v.type === 'Mesh') {
        v.geometry.dispose();
        v.material.dispose();
      }
    })
    this.scene.clear()
    this.renderer.dispose()
    this.renderer.clear()
    this.container = null
    // 相机
    this.camera = null
    // 场景
    this.scene = null
    //渲染器
    this.renderer = null
    // 控制器
    this.controls = null
    // 模型
    this.model = null
    //文件加载器类型
    this.fileLoaderMap = null
    //模型动画列表
    this.modelAnimation = null
    //模型动画对象
    this.animationMixer = null
    this.animationClock = null
    //动画帧
    this.animationFrame = null
    // 轴动画帧
    this.rotationAnimationFrame = null
    // 动画构造器
    this.animateClipAction = null
    // 动画循环方式枚举
    this.loopMap = null
    // 网格辅助线
    this.gridHelper = null
    // 坐标轴辅助线
    this.axesHelper = null
    // 环境光
    this.ambientLight = null
    //平行光
    this.directionalLight = null
    // 平行光辅助线
    this.directionalLightHelper = null
    // 点光源
    this.pointLight = null
    //点光源辅助线
    this.pointLightHelper = null
    //聚光灯
    this.spotLight = null
    //聚光灯辅助线
    this.spotLightHelper = null
    //模型平面
    this.planeGeometry = null
    //模型材质列表
    this.modelMaterialList = []
    this.originalMaterials.clear()
    // 效果合成器
    this.effectComposer = null
    this.outlinePass = null
    // 动画渲染器
    this.renderAnimation = null
    // 碰撞检测
    this.raycaster = null
    // 鼠标位置
    this.mouse = null
    // 辉光效果合成器
    if (this.glowComposer) {
      this.glowComposer.renderer.clear()
      this.glowComposer.renderer.dispose()
    }
    this.glowComposer = null
    // 辉光渲染器
    this.unrealBloomPass = null
    //辉光着色器
    this.shaderPass = null
    // 需要辉光的材质
    this.glowMaterialList = null
    this.materials = null
    // 拖拽对象控制器
    this.transformControls = null
    this.dragGeometryModel = null
    this.glowUnrealBloomPass = false
    // 3d文字渲染器
    this.css3DRenderer = null
    // 3d文字控制器
    this.css3dControls = null
    // 当前拖拽标签信息
    this.dragTag = {}
    //当前标签列表
    this.dragTagList = []
    // 当前拖拽模型信息
    this.activeDragManyModel = {}
  }
}
Object.assign(renderModel.prototype, {
  ...modulesPrototype
})
export default renderModel
